import uvm_pkg::*;
`include "uvm_macros.svh"

class spt_tx_monitor extends uvm_monitor;
	`uvm_component_utils(spt_tx_monitor)
	uvm_analysis_port #(spt_packet) out_port;
	spt_packet mon_tx_tr;
	virtual spt_interface vif;
	
	extern function new(string name,uvm_component parent);
	extern virtual function void build_phase(uvm_phase phase);
	extern virtual task run_phase(uvm_phase phase);
	extern virtual task sample_tx_data();
endclass:spt_tx_monitor

function spt_tx_monitor::new(string name,uvm_component parent);
	super.new(name,parent);
	this.out_port=new("out_port",this);
	`uvm_info(get_type_name(),"new():spt_tx_monitor has been constructed",UVM_HIGH);
endfunction:new

function void spt_tx_monitor::build_phase(uvm_phase phase);
	super.build_phase(phase);
	if(!uvm_config_db#(virtual spt_interface)::get(this,"","vif",this.vif))begin
  		`uvm_error(get_type_name(),"build_phase():Virtual interface in monitor is not configured");
	end
endfunction:build_phase

task spt_tx_monitor::run_phase(uvm_phase phase);
	super.run_phase(phase);
	this.sample_tx_data();
endtask:run_phase

task spt_tx_monitor::sample_tx_data();
	bit[15:0]sample_data[$];
	bit    vld_before;
	this.mon_tx_tr=spt_packet::type_id::create("mon_tx_tr",this);
	
	@(posedge vif.rst_n)
	 while(1) begin
	    @(posedge vif.clk)
	    if(vif.vld == 1'b1)begin
		   sample_data.push_back(vif.data);
	    end
	    else if((vif.vld == 1'b0) && (vld_before==1'b1))begin
	       mon_tx_tr.pkt_data=new[sample_data.size];
		   foreach(sample_data[i])begin;
	          mon_tx_tr.pkt_data[i]=sample_data[i];
	       end
	       sample_data.delete();
	       this.out_port.write(mon_tx_tr);
	       `uvm_info(get_type_name(),$sformatf("sample_stimulus_data():Finish:%s",mon_tx_tr.sprint()),UVM_HIGH);
	    end
	    vld_before=vif.vld;
	end
endtask:sample_tx_data
